package com.avicit.zipkinkafkaesserver.service;

import com.avicit.zipkinkafkaesserver.dao.SpanDao;
import com.avicit.zipkinkafkaesserver.enums.ListTypeEnum;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import zipkin2.Span;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors;

/**
 * jiangyan
 */
@Service
public class SpanService {

    @Autowired
    private SpanDao spanDao;

    public List<List<Span>> spanListFromES() throws IOException {
        return spanDao.spanListFromES();
    }

    /**
     * 时间段查询
     * @param startTime 开始时间 ms
     * @param endTime 结束时间 ms
     * @param limit 取多少条
     * @return
     * @throws IOException
     */
    public List<List<Span>> spanListFromES(long startTime,long endTime, int limit) throws IOException {
        return spanDao.spanListFromES(startTime, endTime, limit);
    }

    public List<List<Span>> spanListFromES(long startTime,long endTime, int limit, String interfaceName) throws IOException {
        return spanDao.spanListFromES(startTime, endTime, limit, interfaceName);
    }
    public List<List<Span>> spanListFromES(long startTime,long endTime, int limit,String serverName, String interfaceName) throws IOException {
        return spanDao.spanListFromES(startTime, endTime, limit, serverName, interfaceName);
    }

    /**
     * 统计所有
     * @return
     * @throws IOException
     */
    public Map<ListTypeEnum, List<Span>> spanList() throws IOException {
        List<List<Span>> spanListFromES = this.spanListFromES();
        Map<ListTypeEnum, List<Span>> listTypeListMap = getDataListMapFromSpanList(spanListFromES);
        return listTypeListMap;
    }

    public Map<ListTypeEnum, List<Span>> spanList(long startTime,long endTime, int limit) throws IOException {
        List<List<Span>> spanListFromES = this.spanListFromES(startTime, endTime,limit);
        Map<ListTypeEnum, List<Span>> listTypeListMap = getDataListMapFromSpanList(spanListFromES);
        return listTypeListMap;
    }
    public Map<ListTypeEnum, List<Span>> spanList(long startTime,long endTime, int limit, String interfaceName) throws IOException {
        List<List<Span>> spanListFromES = this.spanListFromES(startTime, endTime,limit, interfaceName);
        Map<ListTypeEnum, List<Span>> listTypeListMap = getDataListMapFromSpanList(spanListFromES);
        return listTypeListMap;
    }
    public Map<ListTypeEnum, List<Span>> spanList(long startTime,long endTime, int limit, String serverName,String interfaceName) throws IOException {
        List<List<Span>> spanListFromES = this.spanListFromES(startTime, endTime,limit, serverName,interfaceName);
        Map<ListTypeEnum, List<Span>> listTypeListMap = getDataListMapFromSpanList(spanListFromES);
        return listTypeListMap;
    }

    /**
     * 从es 获取的数据 整理 到 Map<ListTypeEnum, List<Span> 中
     * @param spanListFromES
     * @return
     */
    private Map<ListTypeEnum, List<Span>> getDataListMapFromSpanList(List<List<Span>> spanListFromES) {
        final List<Span> serverList = new ArrayList<>();
        final List<Span> clientList = new ArrayList<>();
        List<Span> all = new ArrayList<>();
        Map<ListTypeEnum, List<Span>> listTypeListMap = new ConcurrentHashMap<>();
        for (List<Span> spans : spanListFromES) {
            //获取kind：server
            List<Span> servers = spans.stream().filter(span -> span.kind().name().equals("SERVER")).collect(Collectors.toList());
            //获取kind：client
            List<Span> clients = spans.stream().filter(span -> span.kind().name().equals("CLIENT")).collect(Collectors.toList());
            serverList.addAll(servers);
            clientList.addAll(clients);
        }
        all.addAll(serverList);
        all.addAll(clientList);
        listTypeListMap.put(ListTypeEnum.SERVER, serverList);
        listTypeListMap.put(ListTypeEnum.CLIENT, clientList);
        listTypeListMap.put(ListTypeEnum.ALL, all);
        return listTypeListMap;
    }
}
